using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using ERP.ERPModels.Supplier;
using ERP.Supplier.Dtos;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace ERP.Supplier
{
    /// <summary>
    /// 供应商服务实现
    /// </summary>
    public class SupplierService : ApplicationService, ISupplierService
    {
        private readonly IRepository<ERPModels.Supplier.Supplier, int> _supplierRepository;
        private readonly ILogger<SupplierService> _logger;

        public SupplierService(
            IRepository<ERPModels.Supplier.Supplier, int> supplierRepository,
            ILogger<SupplierService> logger)
        {
            _supplierRepository = supplierRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取供应商列表
        /// </summary>
        public async Task<PagedResultDto<SupplierDto>> GetListAsync(GetSupplierInputDto input)
        {
            try
            {
                var query = await CreateFilteredQueryAsync(input);

                var totalCount = await AsyncExecuter.CountAsync(query);

                query = ApplySorting(query, input);

                query = ApplyPaging(query, input);

                var items = await AsyncExecuter.ToListAsync(query);

                return new PagedResultDto<SupplierDto>(
                    totalCount,
                    ObjectMapper.Map<List<ERPModels.Supplier.Supplier>, List<SupplierDto>>(items)
                );
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取供应商列表失败");
                throw new UserFriendlyException("获取供应商列表失败", ex);
            }
        }

        /// <summary>
        /// 获取供应商详情
        /// </summary>
        public async Task<SupplierDto> GetAsync(int id)
        {
            try
            {
                var supplier = await _supplierRepository.GetAsync(id);
                return ObjectMapper.Map<ERPModels.Supplier.Supplier, SupplierDto>(supplier);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取供应商详情失败, ID: {Id}", id);
                throw new UserFriendlyException("获取供应商详情失败", ex);
            }
        }

        /// <summary>
        /// 创建供应商
        /// </summary>
        public async Task<SupplierDto> CreateAsync(CreateSupplierDto input)
        {
            try
            {
                // 检查编码是否已存在
                var existCode = await _supplierRepository.FirstOrDefaultAsync(s => s.SupplierCode == input.SupplierCode);
                if (existCode != null)
                {
                    throw new UserFriendlyException($"供应商编码 {input.SupplierCode} 已存在");
                }

                var supplier = new ERPModels.Supplier.Supplier
                {
                    SupplierCode = input.SupplierCode,
                    SupplierName = input.SupplierName,
                    SupplierShortName = input.SupplierShortName,
                    EnglishName = input.EnglishName,
                    Level = input.Level,
                    Score = input.Score,
                    Phone = input.Phone,
                    IsEnabled = input.IsEnabled,
                    Remarks = input.Remarks,
                    CreateTime = DateTime.Now
                };

                var result = await _supplierRepository.InsertAsync(supplier, true);
                return ObjectMapper.Map<ERPModels.Supplier.Supplier, SupplierDto>(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建供应商失败, {@Input}", input);
                throw new UserFriendlyException("创建供应商失败", ex);
            }
        }

        /// <summary>
        /// 更新供应商
        /// </summary>
        public async Task<SupplierDto> UpdateAsync(UpdateSupplierDto input)
        {
            try
            {
                // 检查编码是否已存在（排除自身）
                var existCode = await _supplierRepository.FirstOrDefaultAsync(s => s.SupplierCode == input.SupplierCode && s.Id != input.Id);
                if (existCode != null)
                {
                    throw new UserFriendlyException($"供应商编码 {input.SupplierCode} 已存在");
                }

                var supplier = await _supplierRepository.GetAsync(input.Id);

                supplier.SupplierCode = input.SupplierCode;
                supplier.SupplierName = input.SupplierName;
                supplier.SupplierShortName = input.SupplierShortName;
                supplier.EnglishName = input.EnglishName;
                supplier.Level = input.Level;
                supplier.Score = input.Score;
                supplier.Phone = input.Phone;
                supplier.IsEnabled = input.IsEnabled;
                supplier.Remarks = input.Remarks;
                supplier.LastModifyTime = DateTime.Now;

                var result = await _supplierRepository.UpdateAsync(supplier, true);
                return ObjectMapper.Map<ERPModels.Supplier.Supplier, SupplierDto>(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新供应商失败, {@Input}", input);
                throw new UserFriendlyException("更新供应商失败", ex);
            }
        }

        /// <summary>
        /// 删除供应商
        /// </summary>
        public async Task DeleteAsync(int id)
        {
            try
            {
                await _supplierRepository.DeleteAsync(id);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除供应商失败, ID: {Id}", id);
                throw new UserFriendlyException("删除供应商失败", ex);
            }
        }

        /// <summary>
        /// 批量删除供应商
        /// </summary>
        public async Task BatchDeleteAsync(int[] ids)
        {
            try
            {
                await _supplierRepository.DeleteAsync(s => ids.Contains(s.Id));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量删除供应商失败, IDs: {@Ids}", ids);
                throw new UserFriendlyException("批量删除供应商失败", ex);
            }
        }

        /// <summary>
        /// 生成供应商编码
        /// </summary>
        public async Task<string> GenerateSupplierCodeAsync()
        {
            try
            {
                // 获取当前最大的编码
                var maxCode = await _supplierRepository
                    .OrderByDescending(s => s.SupplierCode)
                    .FirstOrDefaultAsync(s => s.SupplierCode.StartsWith("V"));

                string newCode = "V00001";
                
                if (maxCode != null)
                {
                    // 提取数字部分
                    if (int.TryParse(maxCode.SupplierCode.Substring(1), out int codeNum))
                    {
                        codeNum++;
                        newCode = $"V{codeNum:D5}";
                    }
                }

                return newCode;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "生成供应商编码失败");
                throw new UserFriendlyException("生成供应商编码失败", ex);
            }
        }

        /// <summary>
        /// 创建查询条件
        /// </summary>
        private async Task<IQueryable<ERPModels.Supplier.Supplier>> CreateFilteredQueryAsync(GetSupplierInputDto input)
        {
            var query = await _supplierRepository.GetQueryableAsync();

            // 供应商编码
            if (!string.IsNullOrWhiteSpace(input.SupplierCode))
            {
                query = query.Where(s => s.SupplierCode.Contains(input.SupplierCode));
            }

            // 供应商名称
            if (!string.IsNullOrWhiteSpace(input.SupplierName))
            {
                query = query.Where(s => s.SupplierName.Contains(input.SupplierName));
            }

            // 供应商简称
            if (!string.IsNullOrWhiteSpace(input.SupplierShortName))
            {
                query = query.Where(s => s.SupplierShortName.Contains(input.SupplierShortName));
            }

            // 英文名称
            if (!string.IsNullOrWhiteSpace(input.EnglishName))
            {
                query = query.Where(s => s.EnglishName.Contains(input.EnglishName));
            }

            // 是否启用
            if (input.IsEnabled.HasValue)
            {
                query = query.Where(s => s.IsEnabled == input.IsEnabled.Value);
            }

            return query;
        }

        /// <summary>
        /// 应用排序
        /// </summary>
        private IQueryable<ERPModels.Supplier.Supplier> ApplySorting(IQueryable<ERPModels.Supplier.Supplier> query, GetSupplierInputDto input)
        {
            // 如果没有指定排序，默认按ID排序
            if (string.IsNullOrWhiteSpace(input.Sorting))
            {
                return query.OrderByDescending(s => s.Id);
            }

            return query.OrderBy(input.Sorting);
        }

        /// <summary>
        /// 应用分页
        /// </summary>
        private IQueryable<ERPModels.Supplier.Supplier> ApplyPaging(IQueryable<ERPModels.Supplier.Supplier> query, GetSupplierInputDto input)
        {
            return query
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount);
        }
    }
} 